package fun.tan90.wx.pay.rest;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.wechat.pay.java.core.http.DefaultHttpClientBuilder;
import com.wechat.pay.java.core.http.HttpClient;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import fun.tan90.wx.pay.WxPayConstant;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/wx-pay")
public class WxPayController {

    /**
     * 商户号
     * 铁人科技-智慧场馆
     */
    private static final String mchId = WxPayConstant.mchId;

    /**
     * 小程序ID
     * 铁人智慧场馆
     */
    private static final String appId = "wxd85fc53569a9b978";

    /**
     * 陈浩杰
     */
    private static final String openId = "o2Wt6198h5zxnjc-HIx2uVEgIoTs";


    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(15, TimeUnit.SECONDS)
            .writeTimeout(15, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();

    HttpClient httpClient =
            new DefaultHttpClientBuilder()
                    .config(WxPayConstant.CONFIG)
                    .okHttpClient(okHttpClient)
                    .build();

    JsapiService jsapiService = new JsapiService.Builder().httpClient(httpClient).build();

    /**
     * JSAPI/小程序下单
     * 同时生成小程序调起支付必要参数
     */
    @GetMapping("/prepay")
    public JSONObject prepay(Integer total, String outTradeNo) {
        Amount amount = new Amount();
        // 订单总金额，单位为分
        amount.setTotal(total);
        // CNY：人民币，境内商户号仅支持人民币。
        amount.setCurrency("CNY");
        PrepayRequest request = new PrepayRequest();
        request.setAmount(amount);
        request.setAppid(appId);
        request.setMchid(mchId);
        request.setDescription("测试商品标题");
        // 要求6-32个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一。
        request.setOutTradeNo(outTradeNo);
        request.setNotifyUrl(WxPayConstant.ORDER_NOTIFY_URL);


        Payer payer = new Payer();
        payer.setOpenid(openId);
        request.setPayer(payer);

        // 调用下单方法，得到应答
        PrepayResponse response = jsapiService.prepay(request);
        String prepayId = response.getPrepayId();
        log.info("prepayId: {}", prepayId);

        // 小程序调起支付 所需参数
        long timestamp = DateUtil.currentSeconds();
        String nonceStr = IdUtil.nanoId(32);
        String packageStr = "prepay_id=" + prepayId;

        String unSign = StrUtil.format("{}\n{}\n{}\n{}\n",
                appId, timestamp, nonceStr, packageStr);
        String paySign = WxPayConstant.SIGNER.sign(unSign).getSign();

        JSONObject requestPaymentParam = new JSONObject();
        requestPaymentParam.putOnce("timeStamp", timestamp);
        requestPaymentParam.putOnce("nonceStr", nonceStr);
        requestPaymentParam.putOnce("package", packageStr);
        requestPaymentParam.putOnce("signType", "RSA");
        requestPaymentParam.putOnce("paySign", paySign);
        System.out.println(JSONUtil.toJsonPrettyStr(requestPaymentParam));
        return requestPaymentParam;
    }

    /**
     * 商户订单号查询订单
     */
    @GetMapping("/order/query/out-trade-no")
    public Transaction queryByOutTradeNo(String outTradeNo) {
        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        request.setMchid(mchId);
        request.setOutTradeNo(outTradeNo);
        Transaction transaction = jsapiService.queryOrderByOutTradeNo(request);
        System.out.println(JSONUtil.toJsonPrettyStr(transaction));
        return transaction;
    }

    /**
     * 微信支付订单号查询订单
     */
    @GetMapping("/order/query/transaction-id")
    public Transaction queryOrderById(String transactionId) {
        QueryOrderByIdRequest request = new QueryOrderByIdRequest();
        request.setMchid(mchId);
        request.setTransactionId(transactionId);
        Transaction transaction = jsapiService.queryOrderById(request);
        System.out.println(JSONUtil.toJsonPrettyStr(transaction));
        return transaction;
    }

    /**
     * 关闭订单
     */
    @GetMapping("/order/close")
    public void closeOrder(String outTradeNo) {
        CloseOrderRequest request = new CloseOrderRequest();
        request.setMchid(mchId);
        request.setOutTradeNo(outTradeNo);
        jsapiService.closeOrder(request);
    }
}
